package cn.edu.gznu.wecampus.core.auth;

import java.io.PrintWriter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.edu.gznu.wecampus.core.FrameworkConstant;
import cn.edu.gznu.wecampus.core.utils.RestResponseUtils;
import cn.edu.gznu.wecampus.core.web.RestResponse;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class JwtFilter extends BasicHttpAuthenticationFilter {
	
	@Override
	protected boolean isAccessAllowed(ServletRequest request, 
		ServletResponse response, Object mappedValue) {
		try {
			executeLogin(request, response);
			return true;
		} catch(Exception e) {
			try {
				log.error("path: " + ((HttpServletRequest) request).getRequestURL());
				String remote = ((HttpServletRequest) request).getHeader("x-forwarded-for") == null 
					? request.getRemoteAddr() 
					: ((HttpServletRequest) request).getHeader("x-forwarded-for");
				log.error("remote: " + remote);
				log.error(e.getMessage(), e);
				RestResponse res = RestResponseUtils.fail(FrameworkConstant.ERROR_CODE_UNAUTHEN, e.getMessage());
				JSONObject json = (JSONObject) JSON.toJSON(res);
				HttpServletResponse httpResponse = (HttpServletResponse) response;
				httpResponse.setHeader("Content-type", "application/json;charset=UTF-8");
				httpResponse.setHeader("Access-control-Allow-Origin",  "*");
				httpResponse.setHeader("Access-Control-Allow-Methods", "*");
				httpResponse.setHeader("Access-Control-Allow-Headers", "*");
	            PrintWriter writer = httpResponse.getWriter();
	            writer.write(json.toString());
	            writer.flush();
			} catch(Exception ex) {
				throw new RuntimeException(ex);
			}
			return false;
		}
	}
	
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        return false;
    }

	@Override
	protected boolean executeLogin(ServletRequest request, ServletResponse response) {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String token = httpServletRequest.getHeader(FrameworkConstant.JWT_TOKEN_KEY);
		if(StringUtils.isEmpty(token)) {
			token = WebUtils.getCleanParam(request, FrameworkConstant.JWT_TOKEN_KEY);
		}
		JwtToken jwtToken = new JwtToken(token);
		getSubject(request, response).login(jwtToken);
		return true;
	}
}
